001 package EVolve; 002 003 import EVolve.*; 004 import EVolve.exceptions.*; 005 import EVolve.data.*; 006 import EVolve.util.*; 007 008 import java.io.*; 009 import java.util.*; 010 import javax.swing.*; 011 012 import adaptj.*; 013 import adaptj.util.*; 014 import adaptj.toolkits.*; 015 import adaptj.toolkits.continuous.*; 016 017 import it.unimi.dsi.fastUtil.*; 018 019 public class ContinuousDataSource implements DataSource { 020 public static final String DATASOURCE_NAME = "ContinuousDataSource"; 021 022 private BufferedFileReader input; 023 private long mark = 0L; 024 private String currentFileName; 025 026 private Int2ObjectOpenHashMap metrics; 027 private Int2ObjectOpenHashMap triggers; 028 //private Int2ObjectOpenHashMap metricToTriggers; 029 030 private int maxMetricID; 031 private int maxTriggerID; 032 033 // For iterating over all definitions 034 private int currentMetricID; 035 private int currentTriggerID; 036 037 // double arrays are indexed by metric ID, then trigger ID 038 private long[] eventCounts; 039 private ElementDefinition[] definitions; 040 private List[] fields; 041 private EventBuilder[] builders; 042 043 private EntityBuilder triggerEntityBuilder; 044 private Int2ObjectOpenHashMap triggerEntities; 045 046 private LineTokenizer tokenizer; 047 048 private String[] propertyCount = {"time", "count"}; 049 private String[] propertyAmount = {"time", "amount"}; 050 private String[] propertyMetric = {"metric"}; 051 private String[] propertyTrigger = {"trigger"}; 052 053 public void init() throws EVolveException { 054 String fn = EVolve.Scene.getDataFileName(); 055 if (fn == null) { 056 JFileChooser fc = new JFileChooser(EVolve.Scene.getUIManager().getLastDataDir()); 057 if (fc.showOpenDialog(EVolve.Scene.getFrame()) == JFileChooser.APPROVE_OPTION) { 058 try { 059 File f = fc.getSelectedFile(); 060 input = new BufferedFileReader(f); 061 fn = f.getName(); 062 EVolve.Scene.setDataFilename(f.getPath()); 063 EVolve.Scene.getUIManager().setLastDataDir(f.getPath()); 064 EVolve.Scene.setDataFilename(null); 065 } catch (IOException e) { 066 throw new DataProcessingException("IO exception occurred when access data file."); 067 } 068 } else { 069 throw new CancelLoadDataException(); 070 } 071 } else { 072 try { 073 input = new BufferedFileReader(fn); 074 } catch (IOException e) { 075 throw new DataProcessingException("File loading failed."); 076 } 077 } 078 079 currentFileName = fn; 080 tokenizer = new LineTokenizer(); 081 } 082 083 public String getName() { 084 return DATASOURCE_NAME; 085 } 086 087 public String getFileName() { 088 return currentFileName; 089 } 090 091 public void startBuildDefinition() throws DataProcessingException { 092 String line; 093 maxMetricID = 0; 094 maxTriggerID = 0; 095 096 metrics = new Int2ObjectOpenHashMap(); 097 triggers = new Int2ObjectOpenHashMap(); 098 //metricToTriggers = new Int2ObjectOpenHashMap(); 099 100 // Reminder: file format 101 // TRIGGER <id> <trigger description> [INTERVAL] 102 // METRIC <id> <name> 103 // MAP <trigger id> <metric id>+ 104 // <trigger id> <metric id> <metric value> [interval counter] 105 try { 106 while ((line = input.readLine()) != null) { 107 line = line.trim(); 108 if (line.startsWith("#")) { 109 // This input line is a comment -- Skip it 110 } else if (line.equals("")) { 111 // This input line is a blank line -- Skip it 112 } else if (line.startsWith("TRIGGER")) { 113 tokenizer.setLine(line); 114 // Skip "TRIGGER" 115 tokenizer.getNext(); 116 117 int triggerIndex = Integer.parseInt(tokenizer.getNext()); 118 String triggerDesc = tokenizer.getRemaining(); 119 boolean interval = false; 120 if (triggerDesc.endsWith(" INTERVAL")) { 121 interval = true; 122 triggerDesc = triggerDesc.substring(0, triggerDesc.length() - 9); 123 } 124 triggers.put(triggerIndex, triggerDesc); 125 if (maxTriggerID < triggerIndex) { 126 maxTriggerID = triggerIndex; 127 } 128 129 // DEBUG 130 System.out.println("Trigger: " + triggerIndex + " " + triggerDesc + (interval ? " [INTERVAL]" : "")); 131 } else if (line.startsWith("METRIC")) { 132 tokenizer.setLine(line); 133 // Skip "METRIC" 134 tokenizer.getNext(); 135 136 int metricIndex = Integer.parseInt(tokenizer.getNext()); 137 String metricName = tokenizer.getRemaining(); 138 metrics.put(metricIndex, metricName); 139 if (maxMetricID < metricIndex) { 140 maxMetricID = metricIndex; 141 } 142 143 // DEBUG 144 System.out.println("Metric: " + metricIndex + " " + metricName); 145 } else if (line.startsWith("MAP")) { 146 // Ignore at this time 147 /* 148 tokenizer.setLine(line); 149 150 // Skip "MAP" 151 tokenizer.getNext(); 152 153 int triggerIndex = Integer.parseInt(tokenizer.getNext()); 154 while (tokenizer.hasNext()) { 155 int metricIndex = Integer.parseInt(tokenizer.getNext()); 156 IntHashSet triggerSet; 157 if (metricToTriggers.containsKey(metricIndex)) { 158 triggerSet = (IntHashSet) metricToTriggers.get(metricIndex); 159 } else { 160 triggerSet = new IntHashSet("ContinuousDataSource.Metric#" + metricIndex); 161 metricToTriggers.put(metricIndex, triggerSet); 162 } 163 triggerSet.add(triggerIndex); 164 } 165 */ 166 // DEBUG 167 //System.out.println("Map"); 168 } else { 169 System.out.println("Starting to read events"); 170 break; 171 } 172 mark = input.getFilePointer(); 173 } 174 175 eventCounts = new long[maxMetricID + 1];//[maxTriggerID + 1]; 176 definitions = new ElementDefinition[maxMetricID + 1];//[maxTriggerID + 1]; 177 fields = new List[maxMetricID + 1];//[maxTriggerID + 1]; 178 builders = new EventBuilder[maxMetricID + 1];//[maxTriggerID + 1]; 179 180 while (line != null) { 181 tokenizer.setLine(line); 182 // Trigger index 183 //int triggerIndex = Integer.parseInt(tokenizer.getNext()); 184 185 // Metric index 186 int metricIndex = Integer.parseInt(tokenizer.getNext()); 187 188 //eventCounts[metricIndex][triggerIndex] += 1L; 189 eventCounts[metricIndex] += 1L; 190 line = input.readLine(); 191 } 192 } catch (IOException e) { 193 throw new DataProcessingException("File processing failed."); 194 //} catch (ArrayIndexOutOfBoundsException e) { 195 // throw new DataProcessingException("File processing failed (invalid file format)."); 196 } 197 198 currentMetricID = 0; 199 //currentTriggerID = 0; 200 System.out.println("Definitions built. Will iterate next"); 201 System.out.println("Max Metric ID = " + maxMetricID); 202 System.out.println("Max Trigger ID = " + maxTriggerID); 203 } 204 205 public ElementDefinition getNextDefinition() throws DataProcessingException { 206 ElementDefinition result = null; 207 208 if (triggerEntityBuilder == null) { 209 triggerEntityBuilder = new EntityBuilder("Trigger", "Trigger"); 210 return triggerEntityBuilder.buildDefinition(); 211 } 212 213 for (int i = currentMetricID; i <= maxMetricID && result == null; i++, currentMetricID++) { 214 if (eventCounts[i] > 0L) { 215 // Build an event definition for this 216 String eventName = (String) metrics.get(i); // + " - " + triggers.get(j); 217 EventBuilder builder = new EventBuilder(eventName, eventName); 218 List l = new ArrayList(); 219 l.add(builder.buildReferenceDefinition("Trigger", triggerEntityBuilder, propertyTrigger, "Trigger")); 220 l.add(builder.buildValueDefinition("Occurences", propertyCount, "Occurences")); 221 l.add(builder.buildValueDefinition("Value", propertyMetric, "Metric Value")); 222 result = builder.buildDefinition(); 223 224 fields[i] = l; 225 definitions[i] = result; 226 builders[i] = builder; 227 } 228 } 229 230 /* 231 for (int i = currentMetricID; i <= maxMetricID; i++, currentMetricID++) { 232 for (int j = currentTriggerID; j <= maxTriggerID; j++, currentTriggerID++) { 233 if (eventCounts[i][j] > 0L) { 234 // Build an event definition for this 235 String eventName = (String) metrics.get(i); // + " - " + triggers.get(j); 236 EventBuilder builder = new EventBuilder(eventName, eventName); 237 List l = new ArrayList(); 238 l.add(builder.buildValueDefinition("Value", propertyMetric, "Metric Value")); 239 l.add(builder.buildValueDefinition("Occurences", propertyCount, "Occurences")); 240 l.add(builder.buildReferenceDefinition("Trigger", triggerEntityBuilder, propertyTrigger, "Trigger")); 241 result = builder.buildDefinition(); 242 243 fields[i][j] = l; 244 definitions[i][j] = result; 245 builders[i][j] = builder; 246 247 System.out.println("Looked at (" + i + ", " + j + ") --> " + eventName); 248 249 if (result != null) { 250 if (++currentTriggerID > maxTriggerID) { 251 currentTriggerID = 0; 252 currentMetricID++; 253 } 254 255 return result; 256 } 257 } 258 } 259 } 260 */ 261 262 263 264 return result; 265 } 266 267 public long getNumberOfEvents(String definitionName) { 268 for (int i = 0; i < maxMetricID; i++) { 269 ElementDefinition def = definitions[i]; 270 if (def != null && definitionName.equals(def.getName())) { 271 return eventCounts[i]; 272 } 273 } 274 return 0L; 275 } 276 277 public long getTotalNumberOfEvents() { 278 long result = 0L; 279 for (int i = 0; i < maxMetricID; i++) { 280 result += eventCounts[i]; 281 } 282 283 return result; 284 } 285 286 public void startBuildEntity() throws DataProcessingException { 287 currentTriggerID = 0; 288 triggerEntities = new Int2ObjectOpenHashMap(); 289 } 290 291 public Entity getNextEntity() throws DataProcessingException { 292 if (currentTriggerID <= maxTriggerID) { 293 triggerEntityBuilder.newEntity((String) triggers.get(currentTriggerID)); 294 Entity triggerEntity = triggerEntityBuilder.buildEntity(); 295 triggerEntities.put(currentTriggerID, triggerEntity); 296 currentTriggerID++; 297 return triggerEntity; 298 } 299 300 return null; 301 } 302 303 public void startBuildEvent() throws DataProcessingException { 304 try { 305 input.seek(mark); 306 } catch (IOException e) { 307 throw new DataProcessingException("File processing failed"); 308 } 309 } 310 311 public Event getNextEvent() throws DataProcessingException { 312 Event result = null; 313 try { 314 String line; 315 while ((line = input.readLine()) != null) { 316 int currentField = 0; 317 tokenizer.setLine(line); 318 // Trigger index 319 int triggerIndex = Integer.parseInt(tokenizer.getNext()); 320 // Metric index 321 int metricIndex = Integer.parseInt(tokenizer.getNext()); 322 // Metric value 323 double metric = Double.parseDouble(tokenizer.getNext()); 324 325 System.err.println("Trigger: " + triggerIndex + " Metric: " + metricIndex + " Value: " + metric); 326 327 // Interval counter 328 /* 329 int intervalCounter = -1; 330 if (tokenizer.hasNext()) { 331 intervalCounter = Integer.parseInt(tokenizer.getNext()); 332 } 333 */ 334 335 EventBuilder builder = builders[metricIndex]; 336 List l = fields[metricIndex]; 337 338 builder.newEvent(); 339 builder.addValueField((FieldDefinition)l.get(currentField++), (int)(metric * 1000)); 340 builder.addValueField((FieldDefinition)l.get(currentField++), 1); 341 builder.addReferenceField((FieldDefinition)l.get(currentField++), (Entity)triggerEntities.get(triggerIndex)); 342 343 return builder.buildEvent(); 344 } 345 } catch (IOException e) { 346 throw new DataProcessingException("File processing failed"); 347 } 348 349 return null; 350 } 351 352 353 class LineTokenizer { 354 private String line; 355 private int start; 356 private int end; 357 private int len; 358 359 LineTokenizer() { 360 this(null); 361 } 362 363 LineTokenizer(String line) { 364 setLine(line); 365 } 366 367 public void setLine(String line) { 368 this.line = line; 369 if (line != null) { 370 line = line.trim(); 371 len = line.length(); 372 } else { 373 len = -1; 374 } 375 start = 0; 376 end = 0; 377 } 378 379 public boolean hasNext() { 380 return end < len; 381 } 382 383 public String getNext() { 384 if (end < len) { 385 end = line.indexOf(' ', start); 386 if (end < 0) { 387 end = len; 388 } 389 390 String result = line.substring(start, end); 391 start = end + 1; 392 return result; 393 } 394 395 return null; 396 } 397 398 public String getRemaining() { 399 if (end < len) { 400 end = len; 401 return line.substring(start); 402 } 403 404 return null; 405 } 406 } 407 } 408